package com.xiaolei.libraryktx

import android.animation.Animator
import android.animation.ValueAnimator
import android.view.View
import android.view.ViewTreeObserver
import android.view.animation.LinearInterpolator
import com.xiaolei.library.Exts.Ext
import com.xiaolei.library.common.OnUnshakClickListener
// 控件是否可见
inline fun <reified T:View> T.isVisible() = Ext.isVisible(this)

inline fun <reified T : View> T.hide() = Ext.hide(this)
inline fun <reified T : View> T.show() = Ext.show(this)
inline fun <reified T : View> T.gone() = Ext.gone(this)
/**
 * 切换VISIBLE显示Viw
 */
inline fun <reified T : View> T.toggleHide() = Ext.toggleHide(this)

/**
 * 测量自定义View的高度
 */
inline fun <reified T : View> T.measureHeight(heightMeasureSpec: Int) =
        Ext.measureHeight(heightMeasureSpec)

/**
 * 测量自定义View的宽度
 */
inline fun <reified T : View> T.measureWidth(widthMeasureSpec: Int) =
        Ext.measureWidth(widthMeasureSpec)

/**
 * 弹出软键盘
 */
inline fun <reified T : View> T.showKeyboard() = Ext.showKeyboard(context, this)

/**
 * 切换GONE显示Viw
 */
inline fun <reified T : View> T.toggleGone() = Ext.toggleGone(this)

/**
 * View 控件像抽屉一样，从顶部抽下来
 */
inline fun <reified T : View> T.expand(
        duration: Long = 200,
        noinline afterAnim: (() -> Unit)? = null
)
{
    val tag = getTag(R.id._xiaolei_view_anim_tag) as? Boolean ?: false
    if (visibility != View.GONE || tag)
    {
        return
    }
    val lp = this.layoutParams
    var mHeight = this.measuredHeight.coerceAtLeast(minimumHeight)
    if (mHeight <= 0)
    {
        measure(0, 0)
        mHeight = this.measuredHeight
    }
    val anim = ValueAnimator.ofInt(0, mHeight)
    anim.addUpdateListener {
        val height = it.animatedValue as Int
        lp.height = height
        this.layoutParams = lp
    }
    anim.duration = duration
    anim.repeatCount = 0
    anim.interpolator = LinearInterpolator()
    anim.addListener(object : Animator.AnimatorListener
    {
        override fun onAnimationRepeat(p0: Animator?) = Unit
        override fun onAnimationStart(p0: Animator?)
        {
            setTag(R.id._xiaolei_view_anim_tag, true)
            show()
        }

        override fun onAnimationCancel(p0: Animator?) = Unit
        override fun onAnimationEnd(p0: Animator?)
        {
            setTag(R.id._xiaolei_view_anim_tag, false)
            afterAnim?.invoke()
        }
    })
    anim.start()
}

/**
 * 收起动画
 */
inline fun <reified T : View> T.collapse(
        duration: Long = 200,
        noinline afterAnim: (() -> Unit)? = null
)
{
    val tag = getTag(R.id._xiaolei_view_anim_tag) as? Boolean ?: false
    if (visibility != View.VISIBLE || tag)
    {
        return
    }
    val lp = this.layoutParams
    val mHeight = this.measuredHeight
    val anim = ValueAnimator.ofInt(mHeight, 0)
    anim.addUpdateListener {
        val height = it.animatedValue as Int
        lp.height = height
        this.layoutParams = lp
    }
    anim.duration = duration
    anim.repeatCount = 0
    anim.interpolator = LinearInterpolator()
    anim.addListener(object : Animator.AnimatorListener
    {
        override fun onAnimationRepeat(p0: Animator?) = Unit
        override fun onAnimationStart(p0: Animator?)
        {
            setTag(R.id._xiaolei_view_anim_tag, true)
        }
        override fun onAnimationCancel(p0: Animator?) = Unit
        override fun onAnimationEnd(p0: Animator?)
        {
            gone()
            lp.height = mHeight
            layoutParams = lp
            measure(0, 0)
            setTag(R.id._xiaolei_view_anim_tag, false)
            afterAnim?.invoke()
        }
    })
    anim.start()
}


/**
 * 当控件测量完成
 */
inline fun <T : View> T.afterMeasured(crossinline f: T.(width: Int, height: Int) -> Unit)
{
    viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener
    {
        override fun onGlobalLayout()
        {
            if (measuredWidth > 0 && measuredHeight > 0)
            {
                viewTreeObserver.removeOnGlobalLayoutListener(this)
                f(measuredWidth, measuredHeight)
            }
        }
    })
}

/**
 * 防止抖动点击事件
 * 500毫秒之内不允许两次点击
 */
inline fun <reified T : View> T.setUnShakeClickListener(crossinline block: (view: T) -> Unit)
{
    Ext.setUnShakeClickListener(this, object : OnUnshakClickListener()
    {
        override fun onClick(view: View, lastClickTime: Long)
        {
            if (view is T)
            {
                block.invoke(view)
            }
        }
    })
}